package org.xxpay.apibase.util;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
* @Description: 压缩工具类
* @author: xxpay
*/
public class ZIPKit {

    private static final Logger logger = LoggerFactory.getLogger(ZIPKit.class);

    /** 读取压缩包内的 **/
    public static String readFileText(String fileName, String charset, InputStream in) throws IOException {

        String result = "";

        ZipInputStream zipInputStream = new ZipInputStream(in);

        //定义ZipEntry置为null,避免由于重复调用zipInputStream.getNextEntry造成的不必要的问题
        ZipEntry ze = null;
        while ((ze = zipInputStream.getNextEntry()) != null) {

            if(ze.getName().equals(fileName)){
                //读取
                BufferedReader br = new BufferedReader(new InputStreamReader(zipInputStream, Charset.forName(charset)));

                String line;
                while ((line = br.readLine()) != null) {
                    result += line + "\n";
                }

            }
        }
        //一定记得关闭流
        zipInputStream.closeEntry();
        in.close();

        return result;
    }


    /** 读取压缩包内的文件MD5值 **/
    public static String getInnerFileMd5(String fileName, InputStream in) throws IOException {

        String result = "";

        ZipInputStream zipInputStream = new ZipInputStream(in);

        //定义ZipEntry置为null,避免由于重复调用zipInputStream.getNextEntry造成的不必要的问题
        ZipEntry ze = null;
        while ((ze = zipInputStream.getNextEntry()) != null) {

            if(ze.getName().equals(fileName)){
                result = DigestUtils.md5Hex(zipInputStream);
            }
        }
        //一定记得关闭流
        zipInputStream.closeEntry();
        in.close();

        return result;
    }


    //校验文件是否合法， 1.文件是否都存在， 2.md5是否合法
    public static void checkFile(byte[] bytes, String pwd){

        try {
            //文件内的MD5
            String md5Val = readFileText("if.check", "UTF-8", new ByteArrayInputStream(bytes)).trim();

            String appJSONMd5 = getInnerFileMd5("app.json", new ByteArrayInputStream(bytes));
            String jarMd5 = getInnerFileMd5("app.jar", new ByteArrayInputStream(bytes));

            if(md5Val.equalsIgnoreCase(DigestUtils.md5Hex(appJSONMd5 + jarMd5 + pwd))){
                return ;
            }

            throw new RuntimeException("接口文件验证失败！");

        } catch (RuntimeException e) {
            throw e;
        }
        catch (Exception e) {
            logger.error("读取文件失败！" , e);
            throw new RuntimeException("读取文件失败！");
        }


    }

    /** 解压到指定目录中 */
    public static void unzipInnerFile(InputStream is, String innerName, String destFile) throws IOException {

        ZipInputStream zipInputStream = new ZipInputStream(is);

        //定义ZipEntry置为null,避免由于重复调用zipInputStream.getNextEntry造成的不必要的问题
        ZipEntry ze = null;
        while ((ze = zipInputStream.getNextEntry()) != null) {

            if(ze.getName().equals(innerName)){

                File file2 = new File(destFile);
                file2.getParentFile().mkdirs();
                file2.createNewFile();
                FileOutputStream out = new FileOutputStream(file2);
                int length = 0;
                byte[] readByte =new byte[1024];
                while((length=zipInputStream.read(readByte,0,1024))!=-1){
                    out.write(readByte, 0, length);
                }
                out.flush();
                out.close();
            }
        }
        //一定记得关闭流
        zipInputStream.closeEntry();
    }


    /** 自动生成if.check 文件， 一般用于生成动态接口的验证文件  **/
    public static void genIfCheckFile(String genFilePath, String pwd){

        FileInputStream jsonFs = null;
        FileInputStream appFs = null;

        try {

            jsonFs = new FileInputStream(new File(genFilePath + File.separator +"app.json"));
            appFs = new FileInputStream(new File(genFilePath + File.separator +"app.jar"));

            String md5Val = DigestUtils.md5Hex(
                    DigestUtils.md5Hex(jsonFs )  +
                            DigestUtils.md5Hex(appFs )  +
                            pwd
            );

            //写入 app.json
            org.apache.commons.io.FileUtils.writeStringToFile(
                    new File( genFilePath + File.separator +"if.check" ), md5Val, "UTF-8");


        } catch (IOException e) {
           logger.error("", e);
        }finally {
            try {
                if(jsonFs != null) jsonFs.close();
                if(appFs != null) appFs.close();
            } catch (Exception e){
                logger.error("", e);
            }
        }
    }


}
